<template>
  <div class="tinymce-box">
    <Editor v-model="content" :init="init" :id="tinymceId" />
  </div>
</template>

<script setup lang="ts">
import { uploadFile } from "@/api/index";
import type { ComputedRef } from "vue";
import type { RawEditorOptions } from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import tinymceInstance from "tinymce/tinymce";
import "tinymce/themes/silver/theme";
import "tinymce/icons/default";
import "tinymce/models/dom";
// 插件
// import 'tinymce/plugins/powerpaste'  付费插件
import "tinymce/plugins/preview";
import "tinymce/plugins/searchreplace";
import "tinymce/plugins/autolink";
import "tinymce/plugins/directionality";
import "tinymce/plugins/visualblocks";
import "tinymce/plugins/visualchars";
import "tinymce/plugins/fullscreen";
import "tinymce/plugins/image";
import "tinymce/plugins/link";
// import "tinymce/plugins/media";
import "tinymce/plugins/code";
import "tinymce/plugins/codesample";
import "tinymce/plugins/table";
import "tinymce/plugins/charmap";
import "tinymce/plugins/pagebreak";
import "tinymce/plugins/nonbreaking";
import "tinymce/plugins/insertdatetime";
import "tinymce/plugins/advlist";
import "tinymce/plugins/lists";
import "tinymce/plugins/wordcount";
import "tinymce/plugins/autosave";
import "tinymce/plugins/emoticons/plugin.min";
import "tinymce/plugins/emoticons/js/emojis.min";
import "tinymce/plugins/anchor";

// 官网文档地址：https://www.tiny.cloud/docs/tinymce/6/
const tinymceId = ref(
  "vue-tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + "")
);
/**
 * @description 类型注解
 * @IEmitProps emit 事件
 * @ToolbarGroup 编辑器工具栏配置
 * @Iprops 父组件传递的数据
 */
interface IEmitProps {
  (e: "update:value", val: string): void;
}
interface ToolbarGroup {
  name?: string;
  items: string[];
}
interface Iprops {
  value: string;
  // 是否只读
  readonly?: boolean;
  toolbar?: string | boolean | string[] | ToolbarGroup[];
  plugins?: string | string[];
  height?: number | string;
  width?: number | string;
  removedMenuitems?: string;
}

// 初始化 编辑器
onMounted(() => {
  tinymceInstance.init({});
});

// 组件销毁
onBeforeUnmount(() => {
  // 销毁对 DOM 的所有内部引用以解决内存泄漏问题
  if (tinymceInstance?.activeEditor?.destroy) {
    tinymceInstance.activeEditor.destroy();
  }
});
// 设置 props 默认值
const props = withDefaults(defineProps<Iprops>(), {
  readonly: false,
  toolbar: () => [
    "blocks fontsize | bold italic underline strikethrough subscript superscript blockquote lineheight | forecolor backcolor removeformat | alignleft aligncenter alignright alignjustify outdent indent | bullist numlist | emoticons link image table | charmap hr insertdatetime pagebreak | cut copy paste pastetext | selectall visualblocks searchreplace | undo redo restoredraft | print preview fullscreen",
  ],
  plugins:
    "emoticons preview searchreplace autolink directionality visualblocks visualchars fullscreen image link code codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave",
  height: 500,
  width: "100%",
  removedMenuitems:
    "newdocument codesample anchor code fullscreen fontfamily fontsize",
    value:""
});
// 编辑器输入值
const content = ref(props.value);

// tinymce 秘钥
// const apiKey = ref("jmo5tbgjyyzxnk9rv18wktvly6sts1k4d0mq5dxzamxvox09");

// init 参数
const init: ComputedRef<RawEditorOptions> = computed(() => {
  return {
    selector: "#" + tinymceId.value, //富文本编辑器的id,
    // skin路径
    skin_url: "/tinymce/skins/ui/oxide",
    // 语言包的路径
    language_url: "/tinymce/langs/zh-Hans.js",
    // 语言类型
    language: "zh-Hans",
    placeholder: "请输入...",
    min_width: 320,
    min_height: 220,
    // 编辑器宽度
    width: props.width,
    // 编辑器高度
    height: props.height,
    // 编辑器宽高是否可变，false-否,true-高可变，'both'-宽高均可
    resize: "both",
    // tiny技术支持信息是否显示
    branding: false,
    // 统计字数栏是否显示
    statusbar: true,
    // 编辑器获取焦点是否添加蓝色轮廓
    highlight_on_focus: true,
    // 是否显示升级促销按钮
    promotion: false,
    font_size_formats: "10px 11px 12px 14px 16px 18px 20px 24px 36px",
    // 自定义 editor 样式
    content_style:
      "p, div {font-size: 14px; margin: 0px; border:0px ; padding: 0px}",
    content_css: "/tinymce/skins/content/default/content.css",
    // 插件
    plugins: props.plugins,
    // 'emoticons preview searchreplace autolink directionality visualblocks visualchars fullscreen image link code codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave', // 插件配置 axupimgs indent2em
    // 工具栏
    toolbar: props.toolbar,
    // [
    //   'blocks fontsize | bold italic underline strikethrough subscript superscript blockquote lineheight | forecolor backcolor removeformat | alignleft aligncenter alignright alignjustify outdent indent | bullist numlist | emoticons link image table | charmap hr insertdatetime pagebreak | cut copy paste pastetext | selectall visualblocks searchreplace | undo redo restoredraft | print preview fullscreen',
    // ],
    // 移除菜单栏 选项 'newdocument codesample anchor code fullscreen fontfamily fontsize'
    removed_menuitems: props.removedMenuitems,
    // 图片是否可粘贴
    paste_data_images: true,
    // 保留粘贴样式 默认为 none
    paste_webkit_styles: "all",
    /**
     * 是否启用合并格式功能
     * 但如果保留嵌套或相同的格式元素很重要，则可以禁用此选项 可选：true / false
     * 主要用来提升性能，减少不必要的 DOM
     */
    paste_merge_formats: true,
    // 上传文件类型 结合 file_picker_callback 使用
    // file_picker_types: "media",
    // 编辑器初始化完成回调
    init_instance_callback: (editor: any) => {
      console.log(`Editor: ${editor.id} 初始化完成`);
    },
    // 此处为图片上传处理函数
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    images_upload_handler: (blobInfo: any, _progress: Function) =>
      new Promise((resolve, reject) => {
        if (blobInfo.blob().size / 1024 / 1024 > 2) {
          reject({
            message: "上传失败，图片大小请控制在 2M 以内",
            remove: true,
          });
          return;
        } else {
          let params = new FormData();
          params.append("file", blobInfo.blob());
          params.append("type", "edit");
          uploadFile(params)
            .then((backdata: any) => {
              resolve(backdata.data.website + "/" + backdata.data.img);
              return;
            })
            .catch(() => {
              reject("上传出错，服务器开小差了呢");
              return;
            });
        }
      }),
    file_picker_callback: (callback: Function, _value: any, meta: any) => {
      // Provide alternative source and posted for the media dialog
      // 创建文件选择
      let inputElem: HTMLInputElement = document.createElement("input");
      inputElem.setAttribute("type", "file");
      inputElem.setAttribute("accept", "media");
      inputElem.click();
      inputElem.onchange = () => {
        // 获取文件信息
        let file = inputElem.files![0];
        const formData = new FormData();
        formData.append("file", file);
        // 所有都转成base64文件流,来自官方文档https://www.tiny.cloud/docs/configure/file-image-upload/#file_picker_callback
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function () {
          if (meta.filetype === "media") {
            // 请求成功之后调用 callback
            // eslint-disable-next-line n/no-callback-literal
            callback(
              "https://web-assets.dcloud.net.cn/unidoc/zh/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317%20(3).mp4",
              { title: file.name }
            );
          }
        };
      };
    },
  };
});

// 监听 是否只读
watch(
  () => props.readonly,
  (val) => {
    nextTick(() => {
      if (tinymceInstance?.activeEditor?.mode?.set && val) {
        tinymceInstance?.activeEditor.mode.set("readonly");
      }
    });
  },
  { immediate: true }
);
watch(
  () => props.value,
  (val) => {
      content.value=val 
  },
  { immediate: true }
);
const getContent=()=>{
  return content.value
}
defineExpose({ getContent });
// 定义 emits
// const emits = defineEmits<IEmitProps>();

// // 内容有变化，就更新内容，将值返回给父组件
// watchEffect(() => {
//   console.log(props.value);
//   console.log(content.value);
//   if(props.value!= content.value){
//     content.value=props.value
    
//   }
//   emits("update:value", content.value);
// });
</script>

<style scoped>
.tinymce-box > textarea {
  display: none;
}
</style>
<style>
.tox.tox-tinymce {
  max-width: 100%;
}
</style>
